package com.iakuil.app.common.core.domain;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.iakuil.app.common.core.enums.Results;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 带分页信息的API响应结果
 *
 * <p>{@link PageInfo}简化版本，支持对象转换器。
 * <p>注意：返回的JSON中，data字段值是数组。
 *
 * @param <T> Entity Type
 * @author Kai
 */
@Getter
@Setter
public class PageData<T> extends Result<T> {

    public PageData() {
        super(Results.SUCCESS.getCode(), Results.SUCCESS.getMessage());
    }

    /**
     * 结果集
     */
    @JsonProperty("data")
    private List<T> records;

    /**
     * 分页信息
     */
    private Pagination pagination;

    protected PageData(List<T> records, Pagination pagination) {
        this.records = records;
        this.pagination = pagination;
    }

    public PageData(long total, List<T> records, int pageNum, int pageSize, int pages) {
        this.records = records;
        this.pagination = new Pagination(total, pageNum, pageSize, pages);
    }

    public PageData(List<T> records) {
        if (records instanceof Page<T> page) {
            this.pagination = new Pagination(page.getTotal(), page.getPageNum(), page.getPageSize(), page.getPages());
        } else {
            // 即使没有发生分页，也要使参数正确
            int size = records == null ? 0 : records.size();
            this.pagination = new Pagination(size, 1, size, 1);
        }

        this.records = records == null ? Collections.emptyList() : records;
    }

    /**
     * 将PageData中的Entity转换为DTO/VO
     *
     * @param converter 转换函数
     * @return 转换后的对象列表和原来的分页信息
     */
    public <U> PageData<U> map(Function<? super T, ? extends U> converter) {
        return new PageData<>(
            this.records.stream().map(converter).collect(Collectors.toList()),
            this.pagination
        );
    }

    @Override
    public void setData(T data) {
        throw new UnsupportedOperationException("不支持的方法");
    }

    @Getter
    @Setter
    @AllArgsConstructor
    public static class Pagination {
        private long total;
        private int pageNum;
        private int pageSize;
        private int pages;
    }
}
